﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;

namespace Core
{
    internal enum ConnectState
    {
        None,
        Connected,
        Disconnecting,
        Disconnected,
    }

    internal class Connecter : IDisposable
    {
        public ConnectState connectState;
        public bool isSending;

        public Socket socket;
        public IPEndPoint ipEndPoint;

        public SocketAsyncEventArgs requestArgs = new SocketAsyncEventArgs();
        public SocketAsyncEventArgs receiveArgs = new SocketAsyncEventArgs();

        public Buffer requestBuffer = new Buffer();
        public Buffer receiveBuffer = new Buffer();

        public Dictionary<uint, TcpSession> sessions = new Dictionary<uint, TcpSession>();
        public TcpSession connectSession;

        public ConcurrentQueue<Action> delayActions = new ConcurrentQueue<Action>();

        public Connecter(Socket connectSocket, IPEndPoint endPoint)
        {
            connectSocket.NoDelay = true;
            socket = connectSocket;
            this.ipEndPoint = endPoint;
        }

        public bool IsValid()
        {
            if (socket == null)
                return false;

            if (connectState != ConnectState.Connected)
                return false;

            return true;
        }

        public void Dispose()
        {
            connectState = ConnectState.None;
            isSending = false;

            socket.Close();
            socket.Dispose();
            socket = null;

            requestArgs.Dispose();
            receiveArgs.Dispose();

            receiveBuffer.Clear();
            requestBuffer.Clear();

            foreach (var session in sessions.Values)
                session.Dispose();
            sessions.Clear();
            connectSession = null;

            while (delayActions.TryDequeue(out var action)) { }
        }
    }
}
